// axios的基础封装

import store from '@/store'
import axios from 'axios'
// 1. 实例化 axios.create({})
// <1>. baseURL: 很域名配置
// <2>. timeout: 接口的超时时间
const instance = axios.create({
  baseURL: 'http://pcapi-xiaotuxian-front-devtest.itheima.net',
  timeout: 10000
})

// 2. 请求拦截器
instance.interceptors.request.use((config) => {
  // 请求头中携带token
  // 在发送请求之前做些什么
  // 注入token
  const token = store.state.user.profile.token
  if (token) {
    // 前面的属性和后面的字符串拼接方式都由后端决定
    // 前端打配合, 后端将来会从固定的属性中去取值然后做固定的判断逻辑
    config.headers.Authorization = 'Bearer ' + token
  }
  return config
}, (error) => {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 3. 响应拦截器
instance.interceptors.response.use((response) => {
  // 1. token失效处理 401 -> 回到login页
  // 2. 简化数据data访问
  // 3. 成功回调和失败回调的执行依据是根据http状态码来的, 200-300走成功, 否则走失败

  // 场景: 后端在接口事实上已经失败的情况下, hettp状态码依旧定义成了200
  // 当后端不是以严格的http状态码决定接口成功失败, 需要前端根据自己自定义字段判断成功失败 --> 成功: return response; 失败: return Promise.reject()
  // 2xx 范围内的状态码都会触发该函数。
  // 对响应数据做点什么
  return response.data
}, (error) => {
  // 超出 2xx 范围的状态码都会触发该函数。
  // 对响应错误做点什么
  return Promise.reject(error)
})

// 4. 封装一个请求函数
/* 要求: 本项目所有的请求方法只有两种(get, post)
        1. 函数名称为 request
        2. 函数的参数为3个: url(接口路径), method(请求方式), requestData(请求参数{对象})
        3. 这个函数不管是get还是post, 在函数内部自动适配axios要求的参数属性名称(get -> params; post -> data)
        4. 函数的执行结果是一个Promise对象, 可以这样来发送请求: request('/', 'get', {}).then(res => {}) */

// 健壮性的问题:防止用户输入的method不是全小写
// 不管它输入的是大写还是小写, 先转化成小写, 再做判断
const request = (url, method, requestData) => {
  return instance({
    url,
    method,
    [method.toLowerCase() === 'get' ? 'params' : 'data']: requestData
  })
}

export default request
